package vd

import (
	"testing"
	"io"
	"bytes"
	"reflect"
	"strings"
	"strconv"
	"compress/gzip"
	"kumachan/standalone/ctn"
)


var sampleObject = [] Shape {
	Point { Name: "O", Position: Vector { 0.0, 0.0 } },
	PointGroup {
		Points: [] Point {
			Point { Name: "A", Position: Vector { 1.0, 1.0 } },
			Point { Name: "B", Position: Vector { -5.0, 7.0 } },
			Point { Name: "C", Position: Vector { 10.0, 15.0 } },
		},
	},
	Circle {
		Center: Vector { 0, 0 },
	},
	Circle {
		Center: Vector { 0.5, 1.5 },
		Radius: 10,
		Border: ctn.Null[float64](),
	},
	Circle {
		Center: Vector { 2.5, 3.5 },
		Radius: 6,
		Border: ctn.Just(2.0),
	},
	Empty {},
}
func makeBigObject(n uint) ([] Shape) {
	var shapes = make([] Shape, 0)
	for i := 0; i < int(n); i += 1 {
		var p = Point {
			Name:     strconv.Itoa(i),
			Position: Vector { X: float64(i*i), Y: float64(3*i + 7) },
		}
		var c = Circle {
			Center: Vector { X: 0, Y: 0 },
			Radius: float64(2*i + 5),
		}
		shapes = append(shapes, p, c)
	}
	return shapes
}
func testSerializeBigGzipped(n uint) ([] byte, string, error) {
	var ts = sampleTransformer
	var obj = makeBigObject(n)
	var buf_raw bytes.Buffer
	var buf_gz bytes.Buffer
	var raw = io.Writer(&buf_raw)
	var compressed = gzip.NewWriter(&buf_gz)
	var t = ts.DetermineType(reflect.TypeOf(obj))
	var err = Serialize(obj, t, ts.Serializer, io.MultiWriter(raw, compressed))
	if err != nil { return nil, "", err }
	err = compressed.Close()
	if err != nil { return nil, "", err }
	var size_raw = len(buf_raw.Bytes())
	var size_gz = float64(len(buf_gz.Bytes())) / 1048576
	return buf_gz.Bytes(), (strconv.Itoa(size_raw) + "B raw | " +
		strconv.FormatFloat(size_gz, 'f', 2, 64) + "M gzipped"), nil
}

func TestSerialize(t *testing.T) {
	t.Log("serialize a sample object")
	var ts, _ = CreateGoStructTransformer(sampleConfig)
	var buf strings.Builder
	var type_ = ts.DetermineType(reflect.TypeOf(sampleObject))
	var err = Serialize(sampleObject, type_, ts.Serializer, &buf)
	if err != nil { t.Fatal(err) }
	t.Log(buf.String())
}

func TestSerializeBigGzipped1e3(t *testing.T) {
	var _, size, err = testSerializeBigGzipped(1000)
	if err != nil { t.Fatal(err) }
	t.Log(size)
}

func TestSerializeBigGzipped1e4(t *testing.T) {
	var _, size, err = testSerializeBigGzipped(10000)
	if err != nil { t.Fatal(err) }
	t.Log(size)
}

func TestSerializeBigGzipped1e5(t *testing.T) {
	var _, size, err = testSerializeBigGzipped(100000)
	if err != nil { t.Fatal(err) }
	t.Log(size)
}


